package com.macro.mall.portal.controller;

import com.macro.mall.common.api.CommonPage;
import com.macro.mall.common.api.CommonResult;
import com.macro.mall.common.exception.ApiException;
import com.macro.mall.common.service.RedisService;
import com.macro.mall.common.util.HttpClient;
import com.macro.mall.model.UmsMember;
import com.macro.mall.model.UmsMemberReceiveAddress;
import com.macro.mall.portal.domain.*;
import com.macro.mall.portal.service.OmsPortalOrderService;
import com.macro.mall.portal.service.UmsMemberReceiveAddressService;
import com.macro.mall.portal.service.UmsMemberService;
import com.macro.mall.wx.sdk.WXPayUtil;
import com.macro.mall.wx.sdk.WxBeanConfig;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 订单管理Controller
 * Created by macro on 2018/8/30.
 */
@Controller
@Api(tags = "OmsPortalOrderController", description = "订单管理")
@RequestMapping("/order")
public class OmsPortalOrderController {
    private final static String OK_RESULT = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
    private final static String ERROR_RESULT = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg></return_msg></xml>";
    Logger logger = LoggerFactory.getLogger(OmsPortalOrderController.class);
    @Autowired
    private OmsPortalOrderService portalOrderService;
    @Autowired
    private UmsMemberService umsMemberService;
    @Autowired
    private UmsMemberReceiveAddressService memberReceiveAddressService;
    @Autowired
    private WxBeanConfig wxBeanConfig;
    @Autowired
    private RedisService redisService;
    @Value("${redis.database}")
    private String REDIS_DATABASE;
    @Value("${redis.key.paySuccess}")
    private String PAY_SUCCESS;
    @ApiOperation("根据购物车信息生成确认单信息")
    @RequestMapping(value = "/generateConfirmOrder", method = RequestMethod.POST,consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public CommonResult<ConfirmOrderResult> generateConfirmOrder(@RequestParam String cartIds) {
        ConfirmOrderResult confirmOrderResult = this.portalOrderService.generateConfirmOrder(cartIds);
        return CommonResult.success(confirmOrderResult);
    }
    /**
     * 根据商品详情页生成确认单信息
     * @author zhouboyu
     * @Date 2020年9月10日
     * @param skuId
     * @param quantity
     * @return
     */
    @ApiOperation("根据商品详情页生成确认单信息")
    @RequestMapping(value = "/generateConfirmOrderOrderItemDetails", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<ConfirmOrderResult> generateConfirmOrderOrderItemDetails(@RequestParam Long skuId,@RequestParam Integer quantity) {
        ConfirmOrderResult confirmOrderResult = this.portalOrderService.generateConfirmOrderOrderItemDetails(skuId,quantity);
        return CommonResult.success(confirmOrderResult);
    }
    /**
     * 根据购物车信息生成确认单信息
     * @author zhouboyu
     * @Date 2020年9月12日
     * @return
     */
    @ApiOperation("获取当前用户的地址库")
    @RequestMapping(value = "/getMemberAddressList", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<List<UmsMemberReceiveAddress>> getMemberAddressList(@RequestParam(required = false, defaultValue = "1") Integer pageNum,
                                                                            @RequestParam(required = false, defaultValue = "5") Integer pageSize) {
        //获取用户收货地址列表
        List<UmsMemberReceiveAddress> memberReceiveAddressList = memberReceiveAddressService.list(umsMemberService.getCurrentMember().getId(), pageSize, pageNum);
        return CommonResult.success(memberReceiveAddressList);
    }

    @ApiOperation("根据购物车信息生成订单")
    @RequestMapping(value = "/generateOrder", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public CommonResult generateOrder(@RequestBody OrderParam orderParam) {
        Long result = portalOrderService.generateOrder(orderParam);
        return CommonResult.success(result, "下单成功");
    }

    /**
     * 商品详情页下单
     * @author zhouboyu
     * @Date 2020年9月10日
     * @param orderParam
     * @return
     */
    @ApiOperation("商品详情页生成订单")
    @RequestMapping(value = "/generateOrderItemDetails", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public CommonResult generateOrderItemDetails(@RequestBody OrderParam orderParam) {
        logger.info("商品详情页生成订单-------------------"+orderParam.getNote());
        Long result = portalOrderService.generateOrderItemDetails(orderParam);
        return CommonResult.success(result, "下单成功");
    }
    /**
     * 获取经纪人下的Member列表
     * @author zhouboyu
     * @Date 2020年9月10日
     * @return
     */
    @ApiOperation("获取经纪人下的Member列表")
    @RequestMapping(value = "/getAgentMembers", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<List<UmsMember>> getAgentMembers() {
        List<UmsMember> members = this.umsMemberService.getAgentMembers();
        return CommonResult.success(members);
    }
    /**
     * 获取用户可用的优惠券
     * @author zhouboyu
     * @Date 2020年9月10日
     * @return
     */
    @ApiOperation("获取用户可用的优惠券")
    @RequestMapping(value = "/getCouponList/{memberId}", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public CommonResult<List<SmsCouponHistoryDetail>> getCouponList(@PathVariable("memberId") Long memberId, @RequestBody OrderParam orderParam) {
        List<SmsCouponHistoryDetail> couponList = this.portalOrderService.getCouponList(memberId, orderParam);
        return CommonResult.success(couponList);
    }

    /**
     * <xml>
     * 	<appid><![CDATA[wx26c1532d7d44fe45]]></appid>                               appid
     * 	<bank_type><![CDATA[OTHERS]]></bank_type>                                   付款银行
     * 	<cash_fee><![CDATA[1]]></cash_fee>                                          现金支付金额
     * 	<fee_type><![CDATA[CNY]]></fee_type>                                        货币种类
     * 	<is_subscribe><![CDATA[N]]></is_subscribe>                                  是否关注公众账号
     * 	<mch_id><![CDATA[1602769538]]></mch_id>                                     商户号
     * 	<nonce_str><![CDATA[pdNiBoWds8SyRVmmtr3iNFlx1M4wzm6t]]></nonce_str>         随机字符串
     * 	<openid><![CDATA[ox0lJ45DKXj5m2zgxsdprXaPEgR0]]></openid>                   用户标识
     * 	<out_trade_no><![CDATA[202009210102000038]]></out_trade_no>                 商户订单号
     * 	<result_code><![CDATA[SUCCESS]]></result_code>                              业务结果
     * 	<return_code><![CDATA[SUCCESS]]></return_code>                              return_code
     * 	<sign><![CDATA[A59A681BC6DD4DE024088DB69579C033]]></sign>                   签名
     * 	<time_end><![CDATA[20200921154914]]></time_end>                             支付完成时间
     * 	<total_fee>1</total_fee>                                                    订单金额
     * 	<trade_type><![CDATA[JSAPI]]></trade_type>                                  交易类型
     * 	<transaction_id><![CDATA[4200000699202009216900670637]]></transaction_id>   微信支付订单号
     * </xml>
     *
     *
     * @param request
     */
    @ApiOperation("用户支付成功的回调")
    @RequestMapping(value = "/paySuccess", method = RequestMethod.POST)
    public void paySuccess(HttpServletRequest request, HttpServletResponse response) {
        String result = ERROR_RESULT;
        StringBuilder sb = new StringBuilder();
        String inputLine;
        try {
            while ((inputLine = request.getReader().readLine()) != null) {
                sb.append(inputLine);
            }
            request.getReader().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        Map<String, String> payMap = new HashMap<>();
        try {
            if(StringUtils.isNotBlank(sb.toString())){
                payMap = WXPayUtil.xmlToMap(sb.toString());
                boolean sign = WXPayUtil.isSignatureValid(payMap, wxBeanConfig.getKey());
                if(sign){
                    String out_trade_no = payMap.get("out_trade_no");
                    String key = REDIS_DATABASE+":"+PAY_SUCCESS+":"+out_trade_no;
                    if("SUCCESS".equals(this.redisService.get(key))){
                        result =  OK_RESULT;
                    }
                    //微信支付
                    Integer count = portalOrderService.paySuccess(out_trade_no,2);
                    if(count>0){
                        this.redisService.set(REDIS_DATABASE+":"+PAY_SUCCESS+":"+out_trade_no,"SUCCESS",60*60*24);
                        result =  OK_RESULT;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            response.getWriter().write(result);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @ApiOperation("自动取消超时订单")
    @RequestMapping(value = "/cancelTimeOutOrder", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult cancelTimeOutOrder() {
        portalOrderService.cancelTimeOutOrder();
        return CommonResult.success(null);
    }
    @ApiOperation("付款")
    @RequestMapping(value = "/wxPay", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult wxPay(HttpServletRequest request, @RequestParam Long orderId,@RequestParam(required = false,defaultValue = "1")Integer type) {
        String ipAddress = HttpClient.getIpAddress(request);
        try {
            Map<String, String> map = this.portalOrderService.wxPay(orderId, ipAddress,type);
            if(!CollectionUtils.isEmpty(map)){
                return CommonResult.success(map);
            }else {
                return CommonResult.failed("支付失败，请稍后再试");
            }
        } catch (ApiException e) {
            return CommonResult.failed(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return CommonResult.failed("请稍后再试");
        }
    }
    @ApiOperation("取消单个超时订单")
    @RequestMapping(value = "/cancelOrder", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult cancelOrder(Long orderId) {
        portalOrderService.sendDelayMessageCancelOrder(orderId);
        return CommonResult.success(null);
    }

    @ApiOperation("按状态分页获取用户订单列表")
    @ApiImplicitParam(name = "status", value = "订单状态：-1->全部；0->待付款；1->待发货；2->已发货；3->已完成；4->已关闭",
            defaultValue = "-1", allowableValues = "-1,0,1,2,3,4", paramType = "query", dataType = "int")
    @RequestMapping(value = "/list", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public CommonResult<Map<String, Object>> list(@RequestParam Integer status,
                                                  @RequestParam(required = false) String productName,
                                                  @RequestParam(required = false, defaultValue = "1") Integer pageNum,
                                                  @RequestParam(required = false, defaultValue = "5") Integer pageSize,
                                                  @RequestParam(required = false, defaultValue = "1") Integer agentSendType) {
        logger.info("productName-----------------------"+productName);
        Map<String, Object> map = portalOrderService.list(status,productName, pageNum, pageSize, 0, agentSendType,null);
        return CommonResult.success(map);
    }
    @ApiOperation("经纪人代下单列表")
    @ApiImplicitParam(name = "status", value = "订单状态：-1->全部；0->待付款；1->待发货；2->已发货；3->已完成；4->已关闭；5->退货中；6->退款中；7->无效订单'",
            defaultValue = "-1", allowableValues = "-1,0,1,2,3,4,5,6,7", paramType = "query", dataType = "int")
    @RequestMapping(value = "/agentReplace/list", method = RequestMethod.POST,consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public CommonResult<Map<String,Object>> agentReplaceList(@RequestParam Integer status,
                                                         @RequestParam(required = false, defaultValue = "1") Integer pageNum,
                                                         @RequestParam(required = false, defaultValue = "5") Integer pageSize,
                                                         @RequestParam(required = false, defaultValue = "1") Integer agentSendType,
                                                         @RequestParam Long memberId) {
        Map<String, Object> map = portalOrderService.list(status,null, pageNum, pageSize, 1, agentSendType,memberId);
        return CommonResult.success(map);
    }
    @ApiOperation("经纪人待处理订单")
    @ApiImplicitParam(name = "status", value = "订单状态：-1->全部；0->待付款；1->待发货；2->已发货；3->已完成；4->已关闭；5->退货中；6->退款中；7->无效订单'",
            defaultValue = "-1", allowableValues = "-1,0,1,2,3,4,5,6,7", paramType = "query", dataType = "int")
    @RequestMapping(value = "/needAgentSend/list", method = RequestMethod.POST,consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    @ResponseBody
    public CommonResult<Map<String,Object>> needAgentSend(@RequestParam Integer status,
                                                                     @RequestParam(required = false, defaultValue = "1") Integer pageNum,
                                                                     @RequestParam(required = false, defaultValue = "5") Integer pageSize,
                                                                     @RequestParam(required = false) Integer agentSendType) {
        Map<String, Object> map = portalOrderService.list(status,null, pageNum, pageSize, 2, agentSendType,null);
        return CommonResult.success(map);
    }

    /**
     * 代下单经纪人处理订单
     * @author zhouboyu
     * @Date 2020年9月14日
     * @param orderId
     * @return
     */
    @ApiOperation("代下单经纪人处理订单")
    @RequestMapping(value = "/agentSend", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<Integer> agentSend(@RequestParam Long orderId) {
        Integer send = this.portalOrderService.agentSend(orderId);
        if(send>0){
            return CommonResult.success(send);
        }else{
            return CommonResult.failed("处理订单失败，请稍后再试");
        }
    }
    @ApiOperation("根据ID获取订单详情")
    @RequestMapping(value = "/detail", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<OmsOrderDetail> detail(@RequestParam Long orderId) {
        OmsOrderDetail orderDetail = portalOrderService.detail(orderId);
        return CommonResult.success(orderDetail);
    }

    /**
     * 根据子订单id获取商品信息（包含组合商品）
     * @author 高强
     * @Date 2020年9月22日
     * @param id
     * @return
     */
    @RequestMapping(value = "/getProductFromOrderItem", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<OrderItemDetail> getProductFromOrderItem(@RequestParam Long id){
        OrderItemDetail productFromOrderItem = portalOrderService.getProductFromOrderItem(id);
        return CommonResult.success(productFromOrderItem);
    }

    @ApiOperation("用户取消订单")
    @RequestMapping(value = "/cancelUserOrder", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult cancelUserOrder(Long orderId ,String note) {
        portalOrderService.cancelOrder(orderId, note,true);
        return CommonResult.success(null);
    }

    @ApiOperation("用户确认收货")
    @RequestMapping(value = "/confirmReceiveOrder", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult confirmReceiveOrder(Long orderId) {
        portalOrderService.confirmReceiveOrder(orderId);
        return CommonResult.success(null);
    }

    @ApiOperation("用户删除订单")
    @RequestMapping(value = "/deleteOrder", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult deleteOrder(Long orderId) {
        portalOrderService.deleteOrder(orderId);
        return CommonResult.success(null);
    }

    /**
     * 获取经纪人库存列表
     * @author 孙晓亮
     * @date 2020年9月21日
     * @param agentId 经纪人id
     * @return
     */
    @ApiOperation("获取经纪人库存列表")
    @RequestMapping(value = "/getAgentSkuList",method = RequestMethod.GET)
    @ResponseBody
    public CommonResult getAgentSkuList(@RequestParam Long agentId,
                                        @RequestParam(required = false) Long productCategoryId,
                                        @RequestParam(required = false,defaultValue = "1") Integer pageNum,
                                        @RequestParam(required = false,defaultValue = "5") Integer pageSize){
        List<AgentSkuListResult>  agentSkuListResults =  portalOrderService.getAgentSkuList(agentId,productCategoryId,pageNum,pageSize);
        return CommonResult.success( CommonPage.restPage(agentSkuListResults));
    }
}
